﻿using System;

namespace StateTheater
{
    public class LatLong
    {
        public double Lat { get; set; }
        public double Long { get; set; }
    }
    static public class Distance
    {
        const double milesPerDeg = 69.04678;
        const double radPer360 = Math.PI / 180.0;

        /// <summary>
        /// Return distance, in miles, between two L/L points.
        /// </summary>
        /// <param name="from">From.</param>
        /// <param name="to">To.</param>
        /// <returns></returns>
        public static double mileDist(LatLong from, LatLong to)
        {
            if (Math.Abs(from.Lat - to.Lat) <= 4.0 &&
                  Math.Abs(from.Long - to.Long) <= 4.0 &&
                  from.Lat >= -70.0 && from.Lat <= 70 &&
                 to.Lat >= -70.0 && to.Lat <= 70.0)
            {
                double cosFact = Math.Cos(((from.Lat + to.Lat) / 2.0) * radPer360);
                double xd = (to.Long - from.Long) * cosFact;
                double yd = (to.Lat - from.Lat);
                return milesPerDeg * Math.Sqrt(xd * xd + yd * yd);
            }
            else
            {
                double fromLat = from.Lat * radPer360;
                double toLat = to.Lat * radPer360;
                double fromLong = from.Long * radPer360;
                double toLong = to.Long * radPer360;
                return milesPerDeg * (180.0 / Math.PI) * Math.Acos(Math.Sin(fromLat) * Math.Sin(toLat) + Math.Cos(fromLat) * Math.Cos(toLat) * Math.Cos(fromLong - toLong));
            }
        }
        /*
	If Abs(y0 - y1) <= 4.0 _
	  AND Abs(x0 - x1) <= 4.0 _
	  AND y0 >= -70.0 AND y0 <= 70.0 _
	  AND y1 >= -70.0 AND y1 <= 70.0 Then
		cosFact = cos(((y0 + y1)/2.0) * radPer360)
		xd = (x1 - x0) * cosFact
		yd = y1 - y0
		mileDistLL = milesPerDeg * Sqr(xd*xd + yd*yd)
	Else
	  ' Wart: The exact formula needs the arccos function -- acos().
	  ' Apparently VBscript's math library does not have that.
	  ' So we return -1 [YIKES!] as an error.
		mileDistLL = -1
         * */
        /*
  	  ' If you can dig up an acos() function, here's the exact formula:
	  '	x0rad = x0 * radPer360
	  '	x1rad = x1 * radPer360
	  '	y0rad = y0 * radPer360
	  '	y1rad = y1 * radPer360
	  '	mileDistLL = perDeg * (180.0/pi) _
	  '		* acos(sin(y0rad) * sin(y1rad) _
	  '			+ cos(y0rad) * cos(y1rad) * cos(x0rad-x1rad))

	End If
End Function
         */
        /*
' atan2(y, x):
'	Return the arctan of y/x, in the range [-pi,+pi].
'	Do the right thing if x is 0, and consider the signs
'	to return the angle in the right quadrent.
'	At least I hope this does the right thing;
'	I don't have my math text handy.
'
Function atan2(y,x)
	pi = 3.15159265
	If Abs(x) > 0.0001 Then
		atan2 = atn(y/x)
		If x < 0 Then
			If y < 0 Then
				atan2 = atan2 - pi
			Else
				atan2 = atan2 + pi
			End If
		End If
	ElseIf y > 0 Then
		atan2 = pi/2
	ElseIf y < 0 Then
		atan2 = -pi/2
	Else
		' y = 0 & x = 0: Should not happen -- atan2(0,0) isn't defined.
		atan2 = 0
	End If
End Function
*/

        public static double Heading(LatLong from, LatLong to)
        {
            double heading = 90.0 - Math.Atan2(to.Lat - from.Lat, to.Long - from.Long) * 180.0 / Math.PI;
            if (heading < 0)
                heading += 360.0;

            double degHdgLL = Math.Round(heading);
            if (degHdgLL > 360.0)
                degHdgLL -= 360.0;
            return degHdgLL;
        }
        /*
' degHdgLL(x0, y0, x1, y1):
'	Return compass heading from x0,y0 to x1,y1, in integral degrees.
'	Values are from 0 to 359: 0 -> north, 90 -> east, etc.
'
Function degHdgLL(x0, y0, x1, y1)
	pi = 3.15159265
	hdg = 90 - atan2(y1-y0, x1-x0)*180.0/pi
	If hdg < 0 Then
		hdg = hdg + 360
	End If
	degHdgLL = Round(hdg,0)
	If degHdgLL > 360 Then
		degHdgLL = degHdgLL - 360
	End If
End Function
         */
        public static string arrowImgForHdg(double heading)
        {
            string url;
	        if (heading >= 337.5 || heading <= 22.5)
		        url = "arrow0.gif";
	        else if (heading <= 67.5)
		        url = "arrow45.gif";
	        else if (heading <= 112.5)
		        url = "arrow90.gif";
	        else if (heading <= 157.5)
		        url = "arrow135.gif";
	        else if (heading <= 202.5)
		        url = "arrow180.gif";
	        else if (heading <= 247.5)
		        url = "arrow225.gif";
	        else if (heading <= 292.5)
		        url = "arrow270.gif";
	        else
		        url = "arrow315.gif";
            return url;
        }
        /*
         * 
   Function arrowImgForHdg(hdg, moreParam)
	If hdg >= 337.5 OR hdg <= 22.5 Then
		url = "arrow0.gif"
	ElseIf hdg <= 67.5 Then
		url = "arrow45.gif"
	ElseIf hdg <= 112.5 Then
		url = "arrow90.gif"
	ElseIf hdg <= 157.5 Then
		url = "arrow135.gif"
	ElseIf hdg <= 202.5 Then
		url = "arrow180.gif"
	ElseIf hdg <= 247.5 Then
		url = "arrow225.gif"
	ElseIf hdg <= 292.5 Then
		url = "arrow270.gif"
	Else
		url = "arrow315.gif"
	End If
	arrowImgForHdg = "<IMG SRC=""" & url & """ WIDTH=25 HEIGHT=25 " _
		& moreParam & ">"
End Function
         */


    }
}
